package com.qinglei.recoup.system.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fasterxml.jackson.databind.JsonNode;
import com.qinglei.recoup.common.domain.CommonRes;
import com.qinglei.recoup.common.domain.RadarFallDownDataDTO;
import com.qinglei.recoup.common.domain.RadarMessage;
import com.qinglei.recoup.common.domain.Tree;
import com.qinglei.recoup.common.exception.RedisConnectException;
import com.qinglei.recoup.system.domain.Bed;
import com.qinglei.recoup.system.domain.BedBO;
import com.qinglei.recoup.system.domain.BedMonitorTime;
import com.qinglei.recoup.system.domain.BedRadarBO;
import com.qinglei.recoup.system.domain.BedTreeAttachBO;
import com.qinglei.recoup.system.domain.Event;
import com.qinglei.recoup.system.domain.EventBedBO;
import com.qinglei.recoup.system.domain.RadarUpVersionVo;
import com.qinglei.recoup.system.pojo.BedMonitorTimeVO;
import com.qinglei.recoup.system.pojo.BedPageParam;
import com.qinglei.recoup.system.pojo.BedRemarksParam;
import com.qinglei.recoup.system.pojo.BedShowVO;
import com.qinglei.recoup.system.pojo.BedStatusVO;
import com.qinglei.recoup.system.pojo.BedVO;
import com.qinglei.recoup.system.pojo.HealthSearchParam;
import com.qinglei.recoup.system.pojo.HealthVO;
import com.qinglei.recoup.system.pojo.MonitorInfoVO;
import com.qinglei.recoup.system.pojo.OnOffMonitorParam;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.remoting.exception.RemotingException;

import java.util.List;
import java.util.Map;

/**
 * @author syp
 */
public interface BedService extends IService<Bed> {

    int TYPE_BED = 1;
    int TYPE_ROOM = 2;
    int TYPE_FLOOR = 3;
    int TYPE_BUILDING = 4;
    int TYPE_ROOT = 5;

    String TREE_ROOM_PREFIX = "r";
    String TREE_FLOOR_PREFIX = "f";
    String TREE_BUILDING_PREFIX = "b";
    String IS_NOT_BIND_BED = "n";
    String TREE_ALL_ID = "a0";

    CommonRes<IPage<BedShowVO>> showPageBed(BedPageParam bedPageParam);

    /**
     * 根据用户查询床位状态列表
     *
     * @param userId
     * @return
     */
    List<BedStatusVO> getBedShowListByUser(Long userId, Integer roleId);

    /**
     * 获取床位树形接口，可以设置附加字段
     *
     * @param disableData
     * @return
     */
    Tree<Bed> getBedTree(BedTreeAttachBO disableData);

    /**
     * 获取床位树形接口，可以设置附加字段
     *
     * @param disableData
     * @return
     */
    Tree<Bed> getBedTree(BedTreeAttachBO disableData, boolean addTotal);

    /**
     * 床位检测仪关闭备注
     *
     * @param bedRemarksParam
     * @return
     */
    CommonRes radarCloseRemark(BedRemarksParam bedRemarksParam);

    /**
     * 床位检测仪开启或关闭
     *
     * @param param@return
     */
    CommonRes onOffMonitor(OnOffMonitorParam param);

    /**
     * 获取床位全名称（包括层，房间名）
     *
     * @param bedId
     * @return
     */
    BedBO getBedFullName(Integer bedId);

    /**
     * 获取床位列表（名称和ID）
     *
     * @return
     */
    List<BedVO> getBedNameList();

    /**
     * 处理监测仪上传用户数据
     *
     * @param message
     */
    void procRadarData(RadarMessage message, boolean isTask) throws MQBrokerException, RemotingException, InterruptedException, MQClientException;

    /**
     * 添加报警事件
     *
     * @param event
     */
    void procAlarmEvent(Event event,Integer subStatus);

    /**
     * 获取监控基本信息（返回开关状态和监测时间段信息）
     *
     * @param bedId
     * @return
     */
    CommonRes<MonitorInfoVO> getMonitorInfo(Integer bedId);

    /**
     * 推送床位当前状态消息
     *
     * @param bedId
     */
    void pushBedCurStatus(Integer bedId);

    /**
     * 推送床位当前状态消息
     * @param bedId
     * @param isForce 是否强制推送，false时如果当前状态为报警状态不推送
     */
    void pushBedCurStatus(Integer bedId, boolean isForce);

    /**
     * 载入床位监控时段到redis
     *
     * @throws RedisConnectException
     */
    void loadBedMonitorTimeRedisCache() throws RedisConnectException;

    /**
     * 添加床位监测时间段到缓存
     *
     * @param bedId
     * @param bedMonitorTime
     * @return 是否是当前监测时间段
     * @throws RedisConnectException
     */
    void addBetMonitorTime(BedMonitorTime bedMonitorTime) throws RedisConnectException;

    /**
     * 更新床位监测时间段缓存
     *
     * @param oldBedMonitorTime
     * @param newBedMonitorTime
     * @throws RedisConnectException
     */
    void updateBetMonitorTime(BedMonitorTime oldBedMonitorTime, BedMonitorTime newBedMonitorTime) throws RedisConnectException;

    /**
     * 删除床位监测时间段缓存
     *
     * @param bedMonitorTime
     * @throws RedisConnectException
     */
    void delBetMonitorTime(BedMonitorTime bedMonitorTime) throws RedisConnectException;

    /**
     * 添加床位监测时间段到缓存
     *
     * @param bed
     * @param bedMonitorTimeVO
     * @return 是否是当前监测时间段
     * @throws RedisConnectException
     */
    boolean addBetMonitorTime(Bed bed, BedMonitorTimeVO bedMonitorTimeVO) throws RedisConnectException;

    /**
     * 设置床位当前监测时间段
     *
     * @param bedMonitorTimeVO
     * @throws RedisConnectException
     */
    void setBedCurMonitorTime(BedMonitorTimeVO bedMonitorTimeVO) throws RedisConnectException;

    /**
     * 删除床位当前监测时间段
     *
     * @param bedId
     * @throws RedisConnectException
     */
    void delBedCurMonitorTime(Integer bedId) throws RedisConnectException;

    /**
     * 获取床位当前监测时间段
     *
     * @param bedId
     * @return
     * @throws RedisConnectException
     */
    BedMonitorTimeVO getBedCurMonitorTime(Integer bedId);

    /**
     * 床位监测时间段结束时的处理
     *
     * @param bedMonitorTimeVO
     */
    void procBedMonitorTimeEnd(BedMonitorTimeVO bedMonitorTimeVO) throws RedisConnectException;

    /**
     * 床位监测时间段开始时的处理
     *
     * @param bedMonitorTimeVO
     */
    void procBedMonitorTimeStart(BedMonitorTimeVO bedMonitorTimeVO) throws RedisConnectException;

    /**
     * 获取床位信息并带有监测仪SN码
     *
     * @param bedId
     * @return
     */
    BedRadarBO getBedWithSn(Integer bedId);

    /**
     * 清除缓存中待接单事件
     *
     * @param eventBedBO
     */
    void delWaitTakeEventCache(EventBedBO eventBedBO);

    /**
     * 根据条件分页查询床
     *
     * @param healthQO
     * @return
     */
    IPage<HealthVO> getHealth(HealthSearchParam healthQO);

    /**
     * 查询床楼层房间名称
     *
     * @param bedId
     * @return
     */
    HealthVO getSleepReport(Integer bedId);

    /**
     * 根据房间id查询床
     *
     * @param roomId
     * @return
     */
    CommonRes<List<Bed>> getBedByRoomId(Integer roomId);

    /**
     * 根据层id查询床
     *
     * @param floorId
     * @return
     */
    List<Bed> getBedByFloorId(Integer floorId);

    /**
     * 根据楼id查询床
     *
     * @param buildingId
     * @return
     */
    List<Bed> getBedByBuildingId(Integer buildingId);
    /**
     * 修改床的 离床阀值时间
     *
     * @param id
     * @param outBedTimeout
     * @return
     */
    Boolean updateOutBedTime(Integer id, String outBedTimeout);

    /**
     * 通过SN号查询床位信息
     * @param sn
     * @return
     */
    Bed getBedBySn(String sn);

    /**
     * 获取用户对应的床位ID列表
     * @param userId
     * @param roleId
     * @return 列表中第一个元素为0表示无对应床位，为-1表示全部床位，其他为床位ID
     */
    List<Integer> getBedIdsByUser(Long userId, Integer roleId);

    BedStatusVO getBedStatusById(Integer bedId);

    List<BedStatusVO> getAllBeds(Long userId, Integer roleId,Integer tenantId);

    void procRadarDataV4(RadarMessage message);

    boolean isBed(Integer bedId);

    boolean isBedV1(Integer bedId);

    boolean isMonitorTime(Integer bedId);

    Bed getBedBySnNoTenantId(String snCode);

    /**
     * 获取在线雷达列表
     * @return
     */
    List<RadarUpVersionVo> getOnlineRadarList(String iotProductKey, String currentVersion);

    void procRadarDataV7(JsonNode radarDataMap,Integer type);

    void procRadarData(String sn, RadarFallDownDataDTO data);
}
